home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
wdj0697.zip
/
SHMIDT.ZIP
/
VW32SVC.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-11-14
|
6KB
|
211 lines
title vw32svc
page ,132
.386p
.xlist
include vmm.inc
.list
PDDB typedef ptr VxD_Desc_Block
; opcode for the relative jump instruction for the jump stub
JMP_JV equ 0e9h
; W32 service jump stub structure
W32STUB struc
Stub_Jmp db JMP_JV ; relative jump opcode
Stub_targ dd ? ; jump target
Stub_prev dd ? ; address of the previous service handler
W32STUB ends
; the structure of a single Win32 service table entry
W32ENTRY struc
W32_Handler dd ? ; service handler
W32_ParamCnt dd ? ; number of DWORD parameters
W32ENTRY ends
VxD_CODE_SEG
; Helper function: finds Win32 service table entry
; for the VXDID + service
; returns: Win32 table entry pointer or 0 if an entry doesn't exist
Get_Win32_Service_Table proc near C uses ecx, service:dword
mov eax, service
ror eax, 16
movzx eax, ax
VMMCall Get_DDB
xor eax, eax
.IF ecx
.IF [ecx].DDB_Flags & DDB_HAS_WIN32_SVCS
mov ecx, [ecx].DDB_Win32_Service_Table
.IF ecx && ([ecx] != eax)
; win32 table exists and has services
movzx eax, word ptr service
; make sure requested service number
; is not too big
.IF eax < [ecx]
lea eax, [ecx+8+eax*8]
.ELSE
xor eax, eax
.ENDIF
.ENDIF
.ENDIF
.ENDIF
ret
Get_Win32_Service_Table endp
Get_Win32_Param_Count proc near C public, service:dword
cCall Get_Win32_Service_Table,<service>
.IF eax
mov eax, [eax].W32_ParamCnt
.ENDIF
ret
Get_Win32_Param_Count endp
; insert hookproc into a chain of VxD Win32 services
; returns a pointer to an address of the previous
; service handler in eax or 0
Hook_Win32_Service proc near C public,service:dword,hookproc:dword
local w32tab:dword
pushad
cCall Get_Win32_Service_Table,<service>
.IF eax
mov w32tab, eax
VMMCall _HeapAllocate,<<type W32STUB>,HEAPZEROINIT>
.IF !ZERO?
; the allocated stub will become a service handler
; it will contain only one instruction: 'JMP hookproc'
mov [eax].Stub_Jmp, JMP_JV ; opcode for near jmp
sub hookproc, eax
sub hookproc,5 ; immediate
push hookproc
pop [eax].Stub_targ
; get previous handler
mov edx, w32tab
mov esi, [edx].W32_Handler
mov [eax].Stub_prev, esi
; make the stub the new handler
mov [edx].W32_Handler, eax
; return a pointer to the previous handler's address
lea eax, [eax].Stub_prev
.ENDIF
.ENDIF
mov [esp].Pushad_EAX, eax
popad
ret
Hook_Win32_Service endp
; remove hookproc from the service chain
; returns eax != 0 if success
Unhook_Win32_Service proc near C public,service:dword,hookproc:dword
pushad
cCall Get_Win32_Service_Table,<service>
.IF eax ; is service valid?
; get current handler's stub address
mov edx, [eax].W32_Handler
; calculate real handler address from the stub address
mov esi, [edx].Stub_targ
add esi, 5
add esi, edx
.IF esi == hookproc
push [edx].Stub_prev
pop [eax].W32_Handler
.ELSE
; traverse the chain of stubs until hookproc is found
.REPEAT
; sanity check
.IF [edx].Stub_Jmp != JMP_JV
; ??? something horrible has happened
xor eax, eax
.BREAK
.ENDIF
; get previously registered stub
mov ecx, [edx].Stub_prev
; calculate real handler address from the stub address
mov esi, [ecx].Stub_targ
add esi, 5
add esi, ecx
.IF esi == hookproc
; ecx -> stub to hookproc
push [ecx].Stub_prev
pop [edx].Stub_prev
mov edx, ecx
.BREAK
.ENDIF
mov edx, ecx
.UNTIL eax != eax ; forever
.ENDIF
VMMCall _HeapFree,<edx,0>
.ENDIF
mov [esp].Pushad_EAX, eax
popad
ret
Unhook_Win32_Service endp
; for each VxD in the DDB chain that provides Win32 services
; call enumeration procedure with pDDB and pWin32SvcTab
Enumerate_Win32_Services proc near C public,enumproc:dword
local ddb:PDDB
local id:dword
pushad
; get the root of the DDB chain
VMMCall VMM_GetDDBList
.WHILE eax
.IF [eax].DDB_Flags & DDB_HAS_WIN32_SVCS
mov edx, [eax].DDB_Win32_Service_Table
.IF edx
; save ddb
mov ddb, eax
; store shifted VxD ID
movzx eax, [eax].DDB_Req_Device_Number
shl eax, 16
mov id, eax
; start with Win32 service 0
xor ecx, ecx
; call enumproc back for every Win32 service
.WHILE ecx < [edx]
push edx
push ecx
or ecx, id
cCall enumproc,<ecx>
or eax, eax
pop ecx
pop edx
.BREAK .IF !ZERO?
inc ecx
.ENDW
; restore ddb
mov eax, ddb
.ENDIF
.ENDIF
; get next in the DDB chain
mov eax, [eax].DDB_Next
.ENDW
popad
ret
Enumerate_Win32_Services endp
VxD_CODE_ENDS
end